﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Steamrunner
{
    class LevelManager : DrawableGameComponent
    {
        SpriteBatch spriteBatch = null;
        LevelFile levelFile = null;

        List<short> tiles = new List<short>();
        
        // tile size
        int tileWidth = 0;
        int tileHeight = 0;
        
        // map size
        int mapWidth = 0;
        int mapHeight = 0;

        Texture2D woodFloor = null;
        Texture2D woodWall = null;
        Texture2D woodIncline = null;

        Texture2D ironFloor = null;
        Texture2D ironWall = null;
        Texture2D ironIncline = null;

        Texture2D copperFloor = null;
        Texture2D copperWall = null;
        Texture2D copperIncline = null;

        public Point TileSize
        {
            get { return new Point(tileWidth, tileHeight); }
        }

        public LevelManager(Game game, SpriteBatch spriteBatch)
            : base(game)
        {
            this.spriteBatch = spriteBatch;
        }

        public override void Initialize()
        {
            levelFile = new LevelFile("level.ini");
            levelFile.Parse();
            
            tiles = levelFile.Shorts;

            // initialize tileWidth, tileHeight
            tileWidth = 32;
            tileHeight = 32;

            // initialize mapWidth, mapHeight
            mapWidth = 906;
            mapHeight = 50;

            base.Initialize();
        }

        protected override void LoadContent()
        {
            woodFloor = Game.Content.Load<Texture2D>(@"Images/Tiles/woodFloor");
            woodWall = Game.Content.Load<Texture2D>(@"Images/Tiles/woodWall");
            woodIncline = Game.Content.Load<Texture2D>(@"Images/Tiles/woodIncline");

            ironFloor = Game.Content.Load<Texture2D>(@"Images/Tiles/ironFloor");
            ironWall = Game.Content.Load<Texture2D>(@"Images/Tiles/ironWall");
            ironIncline = Game.Content.Load<Texture2D>(@"Images/Tiles/ironIncline");

            copperFloor = Game.Content.Load<Texture2D>(@"Images/Tiles/copperFloor");
            copperWall = Game.Content.Load<Texture2D>(@"Images/Tiles/copperWall");
            copperIncline = Game.Content.Load<Texture2D>(@"Images/Tiles/copperIncline");
        }

        public void Draw(GameTime gameTime, Rectangle cameraView)
        {
            Vector2 position = Vector2.Zero;

            for (int y = 0; y < mapHeight; y++)
            {
                for (int x = 0; x < mapWidth; x++)
                {
                    position = GetTilePosition(x, y);
                    if (cameraView.Contains((int)position.X, (int)position.Y))
                    {
                        int tileType = GetTileTypeByTilePos(x, y);

                        switch (tileType)
                        {
                            case (int)Enums.TileType.NOTHING:
                                // DO NOTHING
                                break;
                            case (int)Enums.TileType.WOODFLOOR:
                                spriteBatch.Draw(woodFloor, position, Color.White);
                                break;
                            case (int)Enums.TileType.WOODWALL:
                                spriteBatch.Draw(woodWall, position, Color.White);
                                break;
                            case (int)Enums.TileType.WOODINCLINE:
                                spriteBatch.Draw(woodIncline, position, Color.White);
                                break;
                            case (int)Enums.TileType.IRONFLOOR:
                                spriteBatch.Draw(ironFloor, position, Color.White);
                                break;
                            case (int)Enums.TileType.IRONWALL:
                                spriteBatch.Draw(ironWall, position, Color.White);
                                break;
                            case (int)Enums.TileType.IRONINCLINE:
                                spriteBatch.Draw(ironIncline, position, Color.White);
                                break;
                            case (int)Enums.TileType.COPPERFLOOR:
                                spriteBatch.Draw(copperFloor, position, Color.White);
                                break;
                            case (int)Enums.TileType.COPPERWALL:
                                spriteBatch.Draw(copperWall, position, Color.White);
                                break;
                            case (int)Enums.TileType.COPPERINCLINE:
                                spriteBatch.Draw(copperIncline, position, Color.White);
                                break;
                        }
                    }
                }
            }

            base.Draw(gameTime);
        }

        private Vector2 GetTilePosition(int x, int y)
        {
            Vector2 temp;

            temp.X = x * tileWidth;
            temp.Y = y * tileHeight;

            return temp;
        }

        private short GetTileTypeByTilePos(int x, int y)
        {
            return tiles[y * mapWidth + x];
        }

        public short GetTileTypeByScreenPos(Vector2 position)
        {
            int tileX = 0;
            int tileY = 0;
            ScreenToTile((int)position.X, (int)position.Y, ref tileX, ref tileY);
            return GetTileTypeByTilePos(tileX, tileY);
        }

        private void ScreenToTile(int screenX, int screenY, ref int tileX, ref int tileY)
        {
            tileX = screenX / tileWidth;
            tileY = screenY / tileHeight;
        }

        public short GetTileTypeByIndex(int index)
        {
            return tiles[index];
        }

        public float GetTopYForTile(Vector2 position)
        {
            float topY = 0f;

            int tileX = 0;
            int tileY = 0;
            ScreenToTile((int)position.X, (int)position.Y, ref tileX, ref tileY);
            topY = GetTilePosition(tileX, tileY).Y;

            return topY;
        }

        public float GetTopLeftXForTile(Vector2 position)
        {
            float topLeftX = 0f;

            int tileX = 0;
            int tileY = 0;
            ScreenToTile((int)position.X, (int)position.Y, ref tileX, ref tileY);
            topLeftX = GetTilePosition(tileX, tileY).X;

            return topLeftX;
        }
    }
}
